﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace CustomControls
{
    public partial class SingleSlider : UserControl
    {
        public event EventHandler ValueChanged;

        private enum SelectedMarker { Right, None }
        private SelectedMarker marker = SelectedMarker.None;
        private Point[] polygonRightPoints = new Point[3];
        private Point mouseStartPosition;
        private Rectangle sliderRectangle;

        private StringFormat rightAlignedFormat;
        private StringFormat leftAlignedFormat;

        private int maxValue;
        public int MaxValue
        {
            get { return maxValue; }
            set { maxValue = value; }
        }
        public Brush ColorBrush { get; set; }
        public Brush DisabledColorBrush { get; set; }
       
        private int _value;
        public int Value
        {
            get { return _value; }
            set {
                
                if (value > maxValue)
                {
                    _value = maxValue;
                }
                
                else
                {
                    _value = value;
                }
                try
                {
                    ValueChanged(this, new EventArgs());
                }
                catch { }
            }
        }
        public SingleSlider()
        {
            InitializeComponent();
            DoubleBuffered = true;
            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            ColorBrush = new LinearGradientBrush(new Point(0, 0), new Point(0, sliderPanel.Height), Color.LightBlue, Color.Blue);
            DisabledColorBrush = new LinearGradientBrush(new Point(0, 0), new Point(0, sliderPanel.Height), Color.LightGray, Color.Gray);
            rightAlignedFormat = new StringFormat();
            rightAlignedFormat.Alignment = StringAlignment.Far;
            rightAlignedFormat.LineAlignment = StringAlignment.Near;

            leftAlignedFormat = new StringFormat();
            leftAlignedFormat.Alignment = StringAlignment.Near;
            leftAlignedFormat.LineAlignment = StringAlignment.Near;
        }
   


        private void sliderPanel_Paint(object sender, PaintEventArgs e)
        {
            if (this.DesignMode) return;
            
            e.Graphics.FillRectangle(this.Enabled ? ColorBrush : DisabledColorBrush,
                sliderRectangle);
            SizeF measureString = e.Graphics.MeasureString(Value.ToString(), new Font("Arial", 8));

            double valueToWidth = (double)Value / (double)maxValue * (double)markerPanel.Width;
            e.Graphics.DrawString(Value.ToString(), new Font("Arial", 8), Brushes.Black, new Point((int)valueToWidth, 0), valueToWidth < measureString.Width ? leftAlignedFormat : rightAlignedFormat);
        }

        private void markerPanel_Paint(object sender, PaintEventArgs e)
        {
            if (this.DesignMode) return;

            double valueToWidth = (double)Value / (double)maxValue * (double)markerPanel.Width;
            polygonRightPoints[0] = new Point((int)valueToWidth, 0);
            polygonRightPoints[1] = new Point((int)valueToWidth + 5, markerPanel.Height);
            polygonRightPoints[2] = new Point((int)valueToWidth - 5, markerPanel.Height);
            sliderRectangle = new Rectangle(0, 0,(int)valueToWidth, sliderPanel.Height);
            e.Graphics.FillPolygon(Brushes.Gray, polygonRightPoints);
            
        }

        private void markerPanel_MouseDown(object sender, MouseEventArgs e)
        {
            mouseStartPosition = e.Location;
           

            if (HitTest(polygonRightPoints, mouseStartPosition))
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right || e.Clicks == 2)
                {
                    NumberForm nForm = new NumberForm();
                    nForm.StartPosition = FormStartPosition.Manual;
                    nForm.Location = Cursor.Position;
                    nForm.MinValue = 0;
                    nForm.MaxValue = int.MaxValue;
                    nForm.Value = Value;
                    if (nForm.ShowDialog() == DialogResult.OK)
                    {
                        if (nForm.Value > MaxValue)
                        {
                            MaxValue = nForm.Value;
                        }
                        Value = nForm.Value;
                        this.Invalidate();
                    }
                    nForm.Dispose();
                }
                else
                {
                    marker = SelectedMarker.Right;
                }
            }
           
            else
            {
                marker = SelectedMarker.None;
            }
        }

        private void markerPanel_MouseMove(object sender, MouseEventArgs e)
        {
            Point currMousePosition = e.Location;
            if (currMousePosition.X < 0)
            {
                currMousePosition.X = 0;
            }
            if (currMousePosition.X > markerPanel.Width)
            {
                currMousePosition.X = markerPanel.Width;
            }
            
            
            switch (marker)
            {
                case SelectedMarker.Right:
                    Value = (int)((double)Math.Abs(currMousePosition.X) / (double)markerPanel.Width * (double)maxValue);
                    this.Invalidate(true);
                    break;
            }
        }

        private bool HitTest(Point[] triangle, Point testPoint)
        {
            //Test er folgt mit umschließendem Rechteck
            
                if (testPoint.Y >= triangle[0].Y && testPoint.Y <= triangle[1].Y && //Höhe testen
                testPoint.X >= triangle[2].X && testPoint.X <= triangle[1].X)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            
        }

        private void markerPanel_MouseUp(object sender, MouseEventArgs e)
        {
            marker = SelectedMarker.None;
        }
    }
}
